#include "bsp_pwm.h"
#include "buzzer.h"
#include "bsp_dwt.h"
#include "string.h"

static PWMInstance *buzzer;
// static uint8_t idx;
static BuzzzerInstance *buzzer_list[BUZZER_DEVICE_CNT] = {0};

/**
 * @brief 蜂鸣器初始化
 *
 */
void BuzzerInit() {
    PWM_Init_Config_s buzzer_config = {
        .htim = &htim4,
        .channel = TIM_CHANNEL_3,
        .dutyratio = 0,
        .period = 0.001,
    };
    buzzer = PWMRegister(&buzzer_config);
}

BuzzzerInstance *BuzzerRegister(Buzzer_config_s *config) {
    if (config->alarm_level > BUZZER_DEVICE_CNT) // 超过最大实例数,考虑增加或查看是否有内存泄漏
        while (1);
    BuzzzerInstance *buzzer_temp = (BuzzzerInstance *) malloc(sizeof(BuzzzerInstance));
    memset(buzzer_temp, 0, sizeof(BuzzzerInstance));

    buzzer_temp->alarm_level = config->alarm_level;
    buzzer_temp->loudness = config->loudness;
    buzzer_temp->octave = config->octave;
    buzzer_temp->alarm_state = ALARM_OFF;

    buzzer_list[config->alarm_level] = buzzer_temp;
    return buzzer_temp;
}

void AlarmSetStatus(BuzzzerInstance *buzzer_, AlarmState_e state) {
    buzzer_->alarm_state = state;
}

void BuzzerStartTask() {
#ifndef MuteMode
    //Haruhikage
    PWMSetDutyRatio(buzzer, 0.9f);
    // PWMSetPeriod(buzzer, (float)1 / ReSharpFreq);
    // HAL_Delay(600);
    // PWMSetPeriod(buzzer, (float)1 / DoSharpFreq);
    // HAL_Delay(300);
    // PWMSetPeriod(buzzer, (float)1 / DownSiFreq);
    // HAL_Delay(600);
    // PWMSetPeriod(buzzer, (float)1 / DoSharpFreq);
    // HAL_Delay(300);
    // PWMSetPeriod(buzzer, (float)1 / ReSharpFreq);
    // HAL_Delay(500);
    // PWMSetPeriod(buzzer, (float)1 / MiFreq);
    // HAL_Delay(150);
    // PWMSetPeriod(buzzer, (float)1 / ReSharpFreq);
    // HAL_Delay(300);
    // PWMSetPeriod(buzzer, (float)1 / DoSharpFreq);
    // HAL_Delay(600);
    PWMSetPeriod(buzzer, (float) 1 / FaFreq);
    HAL_Delay(230);
    PWMSetPeriod(buzzer, (float) 1 / SoSharpFreq);
    HAL_Delay(230);
    PWMSetPeriod(buzzer, (float) 1 / LaSharpFreq);
    HAL_Delay(230);
    PWMSetPeriod(buzzer, (float) 1 / UpDoSharpFreq);
    HAL_Delay(230);
    PWMSetDutyRatio(buzzer, 0.0f);
#endif
}

void BuzzerTask(void) {
    BuzzzerInstance *buzz;
    for (size_t i = 0; i < BUZZER_DEVICE_CNT; ++i) {
        buzz = buzzer_list[i];
        if (buzz->alarm_level > ALARM_LEVEL_LOW) {
            continue;
        }
        if (buzz->alarm_state == ALARM_OFF) {
            PWMSetDutyRatio(buzzer, 0);
        } else {
            PWMSetDutyRatio(buzzer, buzz->loudness);
            switch (buzz->octave) {
                case OCTAVE_1:
                    PWMSetPeriod(buzzer, (float) 1 / DoFreq);
                    break;
                case OCTAVE_2:
                    PWMSetPeriod(buzzer, (float) 1 / ReFreq);
                    break;
                case OCTAVE_3:
                    PWMSetPeriod(buzzer, (float) 1 / MiFreq);
                    break;
                case OCTAVE_4:
                    PWMSetPeriod(buzzer, (float) 1 / FaFreq);
                    break;
                case OCTAVE_5:
                    PWMSetPeriod(buzzer, (float) 1 / SoFreq);
                    break;
                case OCTAVE_6:
                    PWMSetPeriod(buzzer, (float) 1 / LaFreq);
                    break;
                case OCTAVE_7:
                    PWMSetPeriod(buzzer, (float) 1 / SiFreq);
                    break;
                default:
                    break;
            }
            break;
        }
    }
}
